package net.lab1024.sa.admin.module.business.supercomputer.sqlgenerator.service;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.supercomputer.datasource.dao.DatasourceDao;
import net.lab1024.sa.admin.module.business.supercomputer.datasource.domain.bo.DataSourceBO;
import net.lab1024.sa.admin.module.business.supercomputer.datatask.dao.DatataskDao;
import net.lab1024.sa.admin.module.business.supercomputer.datatask.domain.entity.DatataskEntity;
import net.lab1024.sa.admin.module.business.supercomputer.sqlgenerator.domain.entity.DataConfigEntity;
import net.lab1024.sa.admin.module.business.supercomputer.sqlgenerator.domain.vo.SqlTextVO;
import net.lab1024.sa.base.common.exception.BusinessException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
@Service
public class SqlGeneratorService {
    @Resource
    private DatataskDao datataskDao;

    @Resource
    private DatasourceDao datasourceDao;

    @Resource
    SqlGeneratorTemplateService sqlGeneratorTemplateService;

    public SqlTextVO getSQL(Integer taskId) throws IOException {
        //1.从Datatask获取传输配置信息
        Integer dataSourceId = datataskDao.selectById(taskId).getDataSourceId();
        String path = datataskDao.selectById(taskId).getTransportAddress();

        DataSourceBO dataSourceBO = new DataSourceBO();
        //获得源数据
        dataSourceBO = datasourceDao.getById(dataSourceId);
        //转换数据库中取出的JSON串
        try {
            dataSourceBO.setSourceColumns(SQLJsonToJava(dataSourceBO.getSourceColumns()));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //创建配置信息对象
        DataConfigEntity dataConfigEntity = new DataConfigEntity();

        //处理conn的JSON串
        try {
            extractDatabaseConfig(dataSourceBO.getConnInformation(),dataConfigEntity);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
            throw new BusinessException("ConnInfo解析出错");
        }
        dataConfigEntity.setTableName(dataSourceBO.getSourceTablename());//设置表名


        DatataskEntity datataskEntity = new DatataskEntity();
        datataskEntity.setDataSourceId(dataSourceId);

        Map<String, String> columns = new HashMap<>();
        //解析字段存储
        try {
            columns = extractFieldInfo(dataSourceBO.getSourceColumns(), dataConfigEntity);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
            throw new BusinessException("columns字段解析出错");
        }

        //将SQL的类型进行转换
        columns = sqlGeneratorTemplateService.sqlToFlink(columns);
        //3.调用模版生成器,进行模版生成
        String source = sqlGeneratorTemplateService.getSource(dataConfigEntity,columns);
        String sink = sqlGeneratorTemplateService.getSink(dataConfigEntity,columns,path);
        SqlTextVO sqlTextVO = new SqlTextVO();
        sqlTextVO.setSink(sink);
        sqlTextVO.setSource(source);
        //4.将结果进行输出
        return sqlTextVO;
    }
    public static void extractDatabaseConfig(String jsonString,DataConfigEntity dataConfig) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();

        // 解析 JSON 字符串
        JsonNode jsonNode = objectMapper.readTree(jsonString);

        // 获取 URL、username 和 password
        String url = jsonNode.get("url").asText();
        String username = jsonNode.get("username").asText();
        String password = jsonNode.get("password").asText();

        // 提取 IP、端口和数据库名
        String ip = extractIp(url);
        String port = extractPort(url);
        String databaseName = extractDatabaseName(url);

        dataConfig.setIp(ip);
        dataConfig.setPort(port);
        dataConfig.setDataBaseName(databaseName);
        dataConfig.setUserName(username);
        dataConfig.setPassword(password);
    }

    /**
     * Json串处理方法
     * @param url
     * @return
     */
    private static String extractIp(String url) {
        // 从 URL 中提取 IP 地址
        return url.split("://")[1].split(":")[0]; // 获取 IP 部分
    }
    private static String extractPort(String url) {
        // 从 URL 中提取端口
        String[] parts = url.split(":");
        if (parts.length > 2) {
            return parts[3].split("/")[0]; // 提取端口
        }
        return null;
    }

    private static String extractDatabaseName(String url) {
        // 从 URL 中提取数据库名称
        String[] parts = url.split("/");
        if (parts.length > 3) {
            return parts[3]; // 提取数据库名称
        }
        return null;
    }

    /**
     * 解析字段信息
     * @param jsonString
     * @return
     * @throws IOException
     */
    public static Map<String, String> extractFieldInfo(String jsonString,DataConfigEntity dataConfig) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();

        // 解析 JSON 字符串
        JsonNode jsonNode = objectMapper.readTree(jsonString);

        Map<String, String> fieldMap = new HashMap<>();
        String primaryKey = null;

        // 遍历 JSON 节点
        for (String fieldName : (Iterable<String>) jsonNode::fieldNames) {
            // 跳过 primaryKey 字段
            if ("primaryKey".equals(fieldName)) {
                primaryKey = jsonNode.get(fieldName).asText(); // 存储主键
                dataConfig.setKey(primaryKey);
                continue;
            }
            // 将字段名及其类型添加到 map 中
            fieldMap.put(fieldName, jsonNode.get(fieldName).asText());
        }
        // 此处可以根据需要对 primaryKey 进行处理
        return fieldMap;
    }

    /**
     * JSON格式处理
     * @param jsonString
     * @return
     */
    public static String SQLJsonToJava(String jsonString) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();

        // 解析 JSON 字符串为 JsonNode
        JsonNode jsonNode = objectMapper.readTree(jsonString);

        // 提取 columns 节点
        JsonNode columns = jsonNode.get("columns");

        // 创建一个新的 ObjectNode 来存储结果
        ObjectNode result = objectMapper.createObjectNode();

        // 遍历 columns 中的所有字段
        Iterator<String> fieldNames = columns.fieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            result.put(fieldName, columns.get(fieldName).asText());
        }

        // 添加 primaryKey 到 result 中
        result.put("primaryKey", jsonNode.get("primaryKey").asText());

        return objectMapper.writeValueAsString(result);  // 将结果转换为字符串
    }
}

